home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
os2
/
pc2_140.zip
/
SOURCE.ZIP
/
Source
/
Utility.c
< prev
Wrap
Text File
|
1993-04-17
|
62KB
|
1,116 lines
/***********************************************************************\
* PC2.c *
* Copyright (C) by Stangl Roman, 1993 *
* This Code may be freely distributed, provided the Copyright isn't *
* removed, under the conditions indicated in the documentation. *
* *
* Utility.c General functions that are not window procedures. *
* *
\***********************************************************************/
static char RCSID[]="@(#) $Header: Utility.c Version 1.40 04,1993 $ (LBL)";
#define _FILE_ "PC/2 - Utility.c V1.40"
#define INCL_DOSDEVICES
#include "PC2.h" /* User include files */
#include "Error.h"
#include <bsedev.h>
/*--------------------------------------------------------------------------------------*\
* Procedure to initialize a window and its message queue. *
* Req: *
* pHab .......... A pointer to be filled with the anchor block of the window *
* pHmq .......... A pointer to be filled with the message queue of the window *
* Returns: *
* TRUE/FALSE .... If called sucessfully/unsucessfully *
\*--------------------------------------------------------------------------------------*/
BOOL WinStartUp(HAB *pHab, HMQ *pHmq)
{
/* Initialize handle of anchor block */
if((*pHab=WinInitialize(0))==NULLHANDLE)
return(FALSE);
/* Initialize handle of message queue */
if((*pHmq=WinCreateMsgQueue(*pHab, 0))==NULLHANDLE)
return(FALSE);
return(TRUE);
}
/*--------------------------------------------------------------------------------------*\
* Procedure to initialize HELP. *
* Req: *
* hab ........... Anchor block handle *
* pHelpFile ..... A pointer to helppanel filename in PC/2 directory *
* pHwndHelp .... A pointer to a HWND structure *
* Returns: *
* pHwndHelp ..... If called sucessfully/unsucessfully hwnd/NULL *
\*--------------------------------------------------------------------------------------*/
BOOL WinStartHelp(HAB hab, UCHAR *pHelpFile, HWND *pHwndHelp)
{
HELPINIT HelpInit;
HelpInit.cb=sizeof(HELPINIT); /* Size of HELPINIT structure */
HelpInit.ulReturnCode=0; /* Returnvalue from HelpManager */
HelpInit.pszTutorialName=NULL; /* No tutorial */
/* Ressource of Helptable */
HelpInit.phtHelpTable=(PHELPTABLE)MAKEULONG(MAIN_HELP_TABLE, 0xffff);
/* Ressource in .EXE */
HelpInit.hmodHelpTableModule=NULLHANDLE;
/* No handle */
HelpInit.hmodAccelActionBarModule=NULLHANDLE;
HelpInit.idAccelTable=0; /* None */
HelpInit.idActionBar=0; /* None */
/* Window title of help window */
HelpInit.pszHelpWindowTitle="PC/2 - Program Commander/2 Help";
HelpInit.pszHelpLibraryName=pHelpFile; /* Library name of help panel via PC/2 directory */
HelpInit.fShowPanelId=0; /* Panel ID not displayed */
/* *\
* First assume PC2.HLP in HELP path and try to create it from there. *
\* */
*pHwndHelp=WinCreateHelpInstance( /* Create help */
hab, /* Anchor block */
&HelpInit);
/* Test for successful help creation */
if((*pHwndHelp) && (!HelpInit.ulReturnCode))
/* Associate HELP with frame window */
if(WinAssociateHelpInstance(*pHwndHelp, hwndFrame)!=FALSE)
return(TRUE);
/* *\
* Second assume PC2.HLP in PC/2's directory and try to create it from there. *
\* */
HelpInit.ulReturnCode=0; /* Returnvalue from HelpManager */
HelpInit.pszHelpLibraryName="PC2.HLP"; /* Library name of help panel via HELP path */
*pHwndHelp=WinCreateHelpInstance(hab, &HelpInit);
if((*pHwndHelp) && (!HelpInit.ulReturnCode))
if(WinAssociateHelpInstance(*pHwndHelp, hwndFrame)!=FALSE)
return(TRUE);
*pHwndHelp=NULLHANDLE;
return(FALSE);
}
/*--------------------------------------------------------------------------------------*\
* Procedure to close a window and its message queue. *
* Req: *
* pHwndHelp ..... A pointer to HELP window handle *
* pHab .......... A pointer to extract the anchor block of the window *
* pHmq .......... A pointer to extract message queue of the window *
* Returns: *
* TRUE/FALSE .... If called sucessfully/unsucessfully *
\*--------------------------------------------------------------------------------------*/
BOOL WinCloseDown(HWND *pHwndHelp, HAB *pHab, HMQ *pHmq)
{
if(!*pHwndHelp) /* Release HELP */
WinDestroyHelpInstance(*pHwndHelp);
if(*pHmq!=NULLHANDLE) /* Release handle of message queue */
WinDestroyMsgQueue(*pHmq);
if(*pHab!=NULLHANDLE) /* Release handle of anchor block */
WinTerminate(*pHab);
/* Any error during WinStartUp */
if((*pHab==NULLHANDLE) || (*pHmq==NULLHANDLE)) return(FALSE);
else return(TRUE);
}
/*--------------------------------------------------------------------------------------*\
* A SESSIONDATA data structure is used to extract the parameters to start a new *
* session. If sucessfull, additional parameters are extracted to set the priority of *
* the new session. *
* Req: none *
\*--------------------------------------------------------------------------------------*/
void StartSession(SESSIONDATA *ptrSessionData)
{
STARTDATA StartData;
UCHAR *pucDosSettings;
ULONG SessID;
PID Pid;
APIRET rc;
StartData.Length=50; /* Length of StartData */
/* Independent session */
StartData.Related=SSF_RELATED_INDEPENDENT;
StartData.FgBg=ptrSessionData->FgBg; /* Foreground application */
/* No trace */
StartData.TraceOpt=SSF_TRACEOPT_NONE;
/* Session title string */
StartData.PgmTitle=ptrSessionData->PgmTitle;
/* Program path-name string */
StartData.PgmName=ptrSessionData->PgmName;
/* Input arguments */
StartData.PgmInputs=ptrSessionData->PgmInputs;
/* *\
* Search for user-addable commandline parameter. If one found, display dialog and get *
* it. It will be added to the current arguments. *
\* */
while(TRUE)
{
COMMANDLINEPARAMS CLPParams;
UCHAR ucPgmInputs[EF_SIZE255+1];
INT iTemp;
UCHAR *pucTemp;
strcpy(ucPgmInputs, StartData.PgmInputs);
/* Search for [, break if not found */
if((pucTemp=strchr(ucPgmInputs, '['))==NULL) break;
/* Search for ], break if not found */
if(strchr(pucTemp, ']')==NULL) break;
/* Break commandline parameters into three parts */
for(iTemp=0, pucTemp=StartData.PgmInputs; *pucTemp!='['; iTemp++, pucTemp++)
CLPParams.ucPBefore[iTemp]=*pucTemp;
CLPParams.ucPBefore[iTemp]='\0';
pucTemp++; /* Skip [ */
for(iTemp=0; *pucTemp!=']'; iTemp++, pucTemp++)
CLPParams.ucPUser[iTemp]=*pucTemp;
CLPParams.ucPUser[iTemp]='\0';
pucTemp++; /* Skip ] */
for(iTemp=0; *pucTemp!='\0'; iTemp++, pucTemp++)
CLPParams.ucPAfter[iTemp]=*pucTemp;
CLPParams.ucPAfter[iTemp]='\0';
if(!WinDlgBox( /* Start Startup Parameters dialog box */
HWND_DESKTOP, HWND_DESKTOP, SU_DialogProcedure, 0, SUID_STARTUPDIALOG,
&CLPParams)) /* Initialization data */
{
GEN_ERR(hab, hwndFrame, hwndClient);
break;
}
/* Replace existing commandline parameters with
user-edited ones if OK was pressed */
if(DialogResult==DID_OK) sprintf(StartData.PgmInputs, "%s%s %s",CLPParams.ucPBefore,
CLPParams.ucPUser, CLPParams.ucPAfter);
/* If Cancel was pressed, replace by empty string */
else strcpy(StartData.PgmInputs, "");
break; /* Break out ! */
}
StartData.TermQ=0; /* No termination queue */
StartData.Environment=0; /* No environment */
/* Inherit from PC/2's environment to change to
requested drive & directory */
StartData.InheritOpt=SSF_INHERTOPT_PARENT;
/* Session type */
StartData.SessionType=ptrSessionData->SessionType;
StartData.IconFile=0; /* No icon, use default */
StartData.PgmHandle=0; /* Don't use installation file */
/* Session initial state */
StartData.PgmControl=ptrSessionData->PgmControl;
/* Initial window size */
StartData.InitXPos=ptrSessionData->InitXPos;
StartData.InitYPos=ptrSessionData->InitYPos;
StartData.InitXSize=ptrSessionData->InitXSize;
StartData.InitYSize=ptrSessionData->InitYSize;
/* *\
* Change to the root directory of all non-removable drives. *
\* */
{
ULONG ulDriveNumber; /* Current drive (1=A, 2=B, ...) */
ULONG ulLogicalDriveMap; /* Bit map of available drives (Bit 0=A, 1=B, ...) */
UCHAR ucDrive[]="c:"; /* Current drive */
ULONG ulTemp;
HFILE hfFileHandle; /* File handle of current drive */
ULONG ulActionTaken; /* Action taken on opened file (drive) */
/* Query drive bit map */
rc=DosQueryCurrentDisk(&ulDriveNumber, &ulLogicalDriveMap);
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
for(ulTemp=(ULONG)ucDrive[0]-'a', ulLogicalDriveMap>>=2; ulTemp<=(ULONG)('z'-'a');
ulTemp++, ucDrive[0]++, ulLogicalDriveMap>>=1)
{ /* Loop for drive C: to Z: (blocks of 0s must be
expected because of network drives) */
/* If drive is not attached ignore drive letter */
if((ulLogicalDriveMap&0x1)==0) continue;
/* Open drive device readonly and fail call on error */
rc=DosOpen(ucDrive, &hfFileHandle, &ulActionTaken, 0, FILE_NORMAL,
OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0);
if(rc==NO_ERROR)
{ /* On non-removeable media close it and change to the
root directory of it. Don't change to root directory
on removable media that isn't inserted or to not
attached drives */
rc=DosClose(hfFileHandle);
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
/* 1=A, 2=B, 3=C,... */
rc=DosSetDefaultDisk((ucDrive[0]+1)-'a');
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
rc=DosSetCurrentDir("\\");
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
}
}
}
/* *\
* Test for x:(...] where x is a drive and set the current working drive to this *
* drive. *
\* */
if((strlen(ptrSessionData->PgmDirectory)>=2)
&& (ptrSessionData->PgmDirectory[1]==':'))
{
UCHAR ucDrive;
/* Then get drive letter (only if one's there */
ucDrive=tolower(ptrSessionData->PgmDirectory[0]);
/* 1=A, 2=B, 3=C,... */
rc=DosSetDefaultDisk(++ucDrive-'a');
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
}
/* *\
* Test for a directory and set the current working directory to it, if one exists, *
* set to root directory. *
\* */
if(strlen(ptrSessionData->PgmDirectory)>2)
{ /* Only if there's one */
rc=DosSetCurrentDir(ptrSessionData->PgmDirectory);
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
}
else
{ /* Set to root directory */
rc=DosSetCurrentDir("\\");
if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
}
/* *\
* If we're to start a DOS session, then set the DOS-Settings via the Environment. This *
* is an undocumented feature (the toolkit says that the Environment is reserved and *
* must be 0 for a DOS session. To use the DOS Settings each Setting must be followed *
* by \0 and the last Setting must be followed by two \0s. It seems that some settings *
* won't be set f.e. HW_TIMER=ON, HW_NOSOUND=ON don't work. *
\* */
if((StartData.SessionType==SSF_TYPE_VDM) ||
(StartData.SessionType==SSF_TYPE_WINDOWEDVDM))
{
ULONG ulTemp;
UCHAR *pucTemp;
/* Allocate a temporary space for the Dos Settings */
ulTemp=strlen(ptrSessionData->PgmDosSettings)+2;
pucDosSettings=(UCHAR *)malloc(ulTemp);
strcpy(pucDosSettings, ptrSessionData->PgmDosSettings);
/* Replace all \n by \0 */
for(pucTemp=pucDosSettings; *pucTemp!='\0'; pucTemp++)
if(*pucTemp=='\n') *pucTemp='\0';
*++pucTemp='\0';
StartData.Environment=pucDosSettings;
}
/* *\
* Now start the session, but beware of the error code ERROR_SMG_START_IN_BACKGROUND, *
* which isn't actually an error code, but an informational message we ignore. *
\* */
if(StartData.SessionType==SSF_TYPE_WPSOBJECT)
{
HOBJECT hWPSObject;
/* Find the handle of the WPS object */
hWPSObject=WinQueryObject(SessionData.PgmName);
if(hWPSObject!=NULLHANDLE)
WinSetObjectData(hWPSObject, "OPEN=DEFAULT");
else rc=ERROR_INVALID_HANDLE;
rc=NO_ERROR;
}
else
rc=DosStartSession( /* Start the new session */
&StartData, /* Session data */
&SessID, /* Session ID of new session */
&Pid); /* Process ID of new session */
switch(rc)
{
case NO_ERROR: /* Error codes for errors that are informational */
case ERROR_SMG_START_IN_BACKGROUND:
/* *\
* Now obtain the PID of the process just started, and adjust the priority of all *
* threads within this process to Priority Class and Priority Delta, entered by the *
* user in the STARTSESSION structure StartSession. Convert the Program Name to upper- *
* case, since OS/2 internally seems to use uppercase names. *
\* */
// if(StartData.Related!=SSF_RELATED_INDEPENDENT)
// {
// rc=DosSetPriority(
// PRTYS_PROCESS, /* All the threads of any process */
// ptrSessionData->PriorityClass,
// ptrSessionData->PriorityDelta,
// Pid);
// if(rc!=NO_ERROR) DOS_ERR(rc, hwndFrame, hwndClient);
// }
break;
default:
DOS_ERR(rc, hwndFrame, hwndClient);
}
if((StartData.SessionType==SSF_TYPE_VDM) ||
(StartData.SessionType==SSF_TYPE_WINDOWEDVDM))
free(pucDosSettings);
}
/*--------------------------------------------------------------------------------------*\
* Procedure to load a SESSIONDATA structure from a MENUDATA structure. *
* Req: *
* Empty ......... A BOOL flag that is true if the MENUDATA structure is empty. *
* pMenuData ..... A pointer to a MENUDATA structure to extract the data required *
* for a Menu/Program Installation dialog. *
* pSessionData .. A pointer to a SESSIONDATA structure to write the extracted *
* data into, which is then used in subsequent Menu/Program *
* Installation dialogs window procedures. *
* Returns: *
* TRUE/FALSE .... If called sucessfully/unsucessfully *
\*--------------------------------------------------------------------------------------*/
BOOL LoadMenuData2SessionData(BOOL Empty, MENUDATA *pMenuData, SESSIONDATA *pSessionData)
{
USHORT DesktopSizeX=WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
USHORT DesktopSizeY=WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
strcpy(pSessionData->PgmTitle, pMenuData->PgmTitle);
strcpy(pSessionData->PgmName, pMenuData->PgmName);
strcpy(pSessionData->PgmDirectory, pMenuData->PgmDirectory);
strcpy(pSessionData->PgmInputs, pMenuData->PgmInputs);
strcpy(pSessionData->PgmDosSettings, pMenuData->PgmDosSettings);
/* *\
* Just straight forward copy of data from MENUDATA structure to SESSIONDATA structure. *
\* */
if(Empty==FALSE)
{
pSessionData->SessionType=pMenuData->SessionType;
pSessionData->PgmControl=pMenuData->PgmControl;
pSessionData->FgBg=pMenuData->FgBg;
pSessionData->InitXPos=pMenuData->InitXPos;
pSessionData->InitYPos=pMenuData->InitYPos;
pSessionData->InitXSize=pMenuData->InitXSize;
pSessionData->InitYSize=pMenuData->InitYSize;
pSessionData->PriorityClass=pMenuData->PriorityClass;
pSessionData->PriorityDelta=pMenuData->PriorityDelta;
}
if(Empty==TRUE)
{ /* Empty the pSessionData structure to the default
values of the fields */
pSessionData->SessionType=SSF_TYPE_DEFAULT;
pSessionData->PgmControl=SSF_CONTROL_VISIBLE;
pSessionData->FgBg=SSF_FGBG_FORE;
pSessionData->InitXPos=DesktopSizeX*0.15;
pSessionData->InitYPos=DesktopSizeY*0.15;
pSessionData->InitXSize=DesktopSizeX*0.70;
pSessionData->InitYSize=DesktopSizeY*0.70;
pSessionData->PriorityClass=PRTYC_NOCHANGE;
pSessionData->PriorityDelta=0;
}
return(TRUE);
}
/*--------------------------------------------------------------------------------------*\
* Procedure to save a MENUDATA structure to a SESSIONDATA structure. *
* Req: *
* pMenuData ..... A pointer to a MENUDATA structure to write the data from a *
* Menu/Program Installation dialog. *
* pSessionData .. A pointer to a SESSIONDATA structure to extract the data from, *
* which the user entered. *
* Returns: *
* TRUE/FALSE .... If called sucessfully/unsucessfully *
\*--------------------------------------------------------------------------------------*/
BOOL LoadSessionData2MenuData(MENUDATA *pMenuData, SESSIONDATA *pSessionData)
{
/* Ignore if not changed otherwise release menory
and allocate a new one */
if(strcmp(pMenuData->PgmTitle, pSessionData->PgmTitle)!=0)
{
free(pMenuData->PgmTitle);
pMenuData->PgmTitle=malloc(1+strlen(pSessionData->PgmTitle));
strcpy(pMenuData->PgmTitle, pSessionData->PgmTitle);
}
if(strcmp(pMenuData->PgmName, pSessionData->PgmName)!=0)
{
free(pMenuData->PgmName);
pMenuData->PgmName=malloc(1+strlen(pSessionData->PgmName));
strcpy(pMenuData->PgmName, pSessionData->PgmName);
}
if(strcmp(pMenuData->PgmDirectory, pSessionData->PgmDirectory)!=0)
{
free(pMenuData->PgmDirectory);
pMenuData->PgmDirectory=malloc(1+strlen(pSessionData->PgmDirectory));
strcpy(pMenuData->PgmDirectory, pSessionData->PgmDirectory);
}
if(strcmp(pMenuData->PgmInputs, pSessionData->PgmInputs)!=0)
{
free(pMenuData->PgmInputs);
pMenuData->PgmInputs=malloc(1+strlen(pSessionData->PgmInputs));
strcpy(pMenuData->PgmInputs, pSessionData->PgmInputs);
}
if((SessionData.SessionType==SSF_TYPE_VDM) ||
(SessionData.SessionType==SSF_TYPE_WINDOWEDVDM))
if (strcmp(pMenuData->PgmDosSettings, pSessionData->PgmDosSettings)!=0)
{
free(pMenuData->PgmDosSettings);
/* Last entry must contain a CR, LF */
if(*(pSessionData->PgmDosSettings+strlen(pSessionData->PgmDosSettings))!='\n')
strcat(pSessionData->PgmDosSettings, "\r\n");
pMenuData->PgmDosSettings=malloc(1+strlen(pSessionData->PgmDosSettings));
strcpy(pMenuData->PgmDosSettings, pSessionData->PgmDosSettings);
}
pMenuData->SessionType=pSessionData->SessionType;
pMenuData->PgmControl=pSessionData->PgmControl;
pMenuData->FgBg=pSessionData->FgBg;
pMenuData->InitXPos=pSessionData->InitXPos;
pMenuData->InitYPos=pSessionData->InitYPos;
pMenuData->InitXSize=pSessionData->InitXSize;
pMenuData->InitYSize=pSessionData->InitYSize;
pMenuData->PriorityClass=pSessionData->PriorityClass;
pMenuData->PriorityDelta=pSessionData->PriorityDelta;
return(TRUE);
}
/*--------------------------------------------------------------------------------------*\
* This procedure allocates a MENUDATA structure and initializes it to the default *
* values of an empty structure. *
* Req: *
* none *
* Returns: *
* pMenuData ..... A pointer to an MENUDATA structure. *
\*--------------------------------------------------------------------------------------*/
MENUDATA *AllocateMenuData(void)
{
UCHAR *pU;
MENUDATA *pMenuData;
pMenuData=malloc(sizeof(MENUDATA)); /* Allocate a MENUDATA structure */
pMenuData->Item=ENTRYEMPTY; /* It's an empty structure */
pMenuData->id=0;
pMenuData->hwndItem=NULLHANDLE;
strcpy(pU=malloc(strlen("")+1), "");
pMenuData->PgmTitle=pU; /* Load default values */
strcpy(pU=malloc(strlen("")+1), "");
pMenuData->PgmName=pU;
strcpy(pU=malloc(strlen("")+1), "");
pMenuData->PgmDirectory=pU;
strcpy(pU=malloc(strlen("")+1), "");
pMenuData->PgmInputs=pU;
strcpy(pU=malloc(strlen("")+1), "");
pMenuData->PgmDosSettings=pU;
pMenuData->SessionType=0;
pMenuData->PgmControl=0;
pMenuData->FgBg=0;
pMenuData->InitXPos=0;
pMenuData->InitYPos=0;
pMenuData->InitXSize=0;
pMenuData->InitYSize=0;
pMenuData->PriorityClass=0;
pMenuData->PriorityDelta=0;
pMenuData->Back=NULL;
pMenuData->Submenu=NULL;
pMenuData->Next=NULL;
return(pMenuData);
}
#define GetEntry fgets(Buffer, sizeof(Buffer), Pc2Profile);\
if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');\
else for( ; (*Match==' ') && (*Match!='\0'); Match++);
/*--------------------------------------------------------------------------------------*\
* This recursive procedure loads the popup menu from the profile. *
* Req: *
* pMenuData ..... A pointer to an MENUDATA structure. *
* Returns: *
* none *
\*--------------------------------------------------------------------------------------*/
void LoadMenu(MENUDATA *pMenuData)
{
static UCHAR Buffer[256];
static UCHAR *Match;
static USHORT Flag;
fgets(Buffer, sizeof(Buffer), Pc2Profile);
do
{
/* Should read MENUITEM or SUBMENU BEGIN or
SUBMENU END */
if(strcmp(Buffer, "SUBMENU END\n")==0)
return; /* We are at an end of the list, terminate it
and shell up one level by return() */
pMenuData->id=MenuDataId++; /* Fill with current id and increment id */
if(strcmp(Buffer, "PROFILE END\n")==0) return;
if(strcmp(Buffer, "MENUITEM\n")==0) Flag=ENTRYMENUITEM; else Flag=ENTRYSUBMENU;
/* *\
* Get the entry from the profile, but remove the heading description and the \n from *
* the strings. *
\* */
/* Get the session title */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
Buffer[strlen(Buffer)-1]='\0';
if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');
else for( ; (*Match==' ') && (*Match!='\0'); Match++);
free(pMenuData->PgmTitle);
pMenuData->PgmTitle=malloc(strlen(Match)+1);
strcpy(pMenuData->PgmTitle, Match);
if(Flag==ENTRYMENUITEM)
{ /* If we load a MENUITEM, then load the strings
from the profile */
pMenuData->Item=ENTRYMENUITEM; /* It's a Menuitem */
/* Session path and filename */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
Buffer[strlen(Buffer)-1]='\0';
if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');
else for( ; (*Match==' ') && (*Match!='\0'); Match++);
free(pMenuData->PgmName);
pMenuData->PgmName=malloc(strlen(Match)+1);
strcpy(pMenuData->PgmName, Match);
/* Session working directory */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
Buffer[strlen(Buffer)-1]='\0';
if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');
else for( ; (*Match==' ') && (*Match!='\0'); Match++);
free(pMenuData->PgmDirectory);
pMenuData->PgmDirectory=malloc(strlen(Match)+1);
strcpy(pMenuData->PgmDirectory, Match);
/* Session parameter */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
Buffer[strlen(Buffer)-1]='\0';
if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');
else for( ; (*Match==' ') && (*Match!='\0'); Match++);
free(pMenuData->PgmInputs);
pMenuData->PgmInputs=malloc(strlen(Match)+1);
strcpy(pMenuData->PgmInputs, Match);
/* Test for DOS Settings */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
if(strcmp(Buffer, "DOSSETTINGS BEGIN\n")==0)
{
UCHAR ucBuffer[2049]="";
fgets(Buffer, sizeof(Buffer), Pc2Profile);
while(strcmp(Buffer, "DOSSETTINGS END\n")!=0)
{ /* Add all DOS Settings to temporary buffer */
strcat(ucBuffer, Buffer);
fgets(Buffer, sizeof(Buffer), Pc2Profile);
}
/* Now allocate the exactly required buffer and
copy all DOS Settings there */
free(pMenuData->PgmDosSettings);
pMenuData->PgmDosSettings=malloc(strlen(ucBuffer)+1);
/* Read one line ahead */
strcpy(pMenuData->PgmDosSettings, ucBuffer);
fgets(Buffer, sizeof(Buffer), Pc2Profile);
}
/* Session type */
if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');\
else for( ; (*Match==' ') && (*Match!='\0'); Match++);
pMenuData->SessionType=(USHORT)atol(Match);
/* Session control */
GetEntry;
pMenuData->PgmControl=(USHORT)atol(Match);
/* Start session in fore/background */
GetEntry;
pMenuData->FgBg=(USHORT)atol(Match);
/* X Position */
GetEntry;
pMenuData->InitXPos=(USHORT)atol(Match);
/* Y Position */
GetEntry;
pMenuData->InitYPos=(USHORT)atol(Match);
/* X Size */
GetEntry;
pMenuData->InitXSize=(USHORT)atol(Match);
/* Y Size */
GetEntry;
pMenuData->InitYSize=(USHORT)atol(Match);
/* Priority of session */
GetEntry;
pMenuData->PriorityClass=(ULONG)atol(Match);
/* Delta priority of session */
GetEntry;
pMenuData->PriorityDelta=(LONG)atol(Match);
/* Insert this Menuitem at the end of the Popup-Menu */
if(pMenuData->Back!=NULL)
{ /* This isn't the first item, insert after an
existing item */
if((pMenuData->Back)->Submenu==pMenuData)
/* If this is the first item of a Submenu, then
insert it as this */
SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMenuData), MPFROMLONG((pMenuData->Back)->id));
else
/* Insert item after the existing item */
SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMLONG((pMenuData->Back)->id));
}
else /* This is the first item, insert at the end */
SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMLONG(MIT_END));
}
if(Flag==ENTRYSUBMENU)
{ /* If we load a SUBMENU BEGIN, fill with empty strings */
MENUDATA *pMenuDataTemp;
pMenuData->Item=ENTRYSUBMENU; /* It's a Submenu */
/* Now obtain a entry for a submenu, adjust the
linked list to it and call this procedure with
the new entry recursivly again */
pMenuDataTemp=AllocateMenuData();
pMenuData->Submenu=pMenuDataTemp;
pMenuDataTemp->Back=pMenuData;
/* Insert this Menuitem at the end of the Popup-Menu */
if(pMenuData->Back!=NULL)
{ /* This isn't the first item, insert after an
existing item */
if((pMenuData->Back)->Submenu==pMenuData)
/* If this is the first item of a Submenu, then
insert it as this */
SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMenuData), MPFROMLONG((pMenuData->Back)->id));
else
/* Insert item after the existing item */
SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMLONG((pMenuData->Back)->id));
}
else /* This is the first item, insert at the end */
SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMLONG(MIT_END));
LoadMenu(pMenuDataTemp); /* It's assumed to be an empty entry, which will
be corrected, if the first entry of the Submenu
is found */
}
/* *\
* Now see if we're at the end of the profile. If so, then terminate linked list with *
* 2 Null pointers, otherwise abtain a new menu space and adjust the menu pointer *
* pMenuData to the newly created menu. *
\* */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
if(strcmp(Buffer, "PROFILE END\n")==0)
break; /* Empty lines may follow and feof() then is FALSE
and we loop again, reading invalid input. Avoid
this by breaking out of the loop */
else
{ /* If a SUBMENU END follows ignore it, because
execution will return at beginning of the loop
otherwise add a new item to the end of the
linked list */
if(strcmp(Buffer, "SUBMENU END\n")!=0)
{
MENUDATA *pMenuDataTemp;
pMenuDataTemp=AllocateMenuData();
pMenuData->Next=pMenuDataTemp;
pMenuDataTemp->Back=pMenuData;
pMenuData=pMenuData->Next;
}
}
} while(!feof(Pc2Profile));
return;
}
/*--------------------------------------------------------------------------------------*\
* This recursive procedure saves the popup menu into the profile. *
* Req: *
* pMenuData ..... A pointer to an MENUDATA structure. *
* Returns: *
* none *
\*--------------------------------------------------------------------------------------*/
void SaveMenu(MENUDATA *pMenuData)
{
do
{
if(pMenuData->Item==ENTRYSUBMENU)
{
/* *\
* If this is a SUBMENU, then write the header SUBMENU BEGIN and then write the profile *
* data from teh MENUDATA structure pointet by pMenuData. Then increment the depth *
* counter and call this procedure recursivly again. After coming back, restore the *
* depth counter and write the header SUBMENU END. *
\* */
fprintf(Pc2Profile, "SUBMENU BEGIN\n");
fprintf(Pc2Profile, "PgmTitle: %s\n", pMenuData->PgmTitle);
SaveMenu(pMenuData->Submenu);
fprintf(Pc2Profile, "SUBMENU END\n");
}
if(pMenuData->Item==ENTRYMENUITEM)
{
/* *\
* If it is a MENUITEM, so write the header MENUITEM and then write the profile data *
* from the MENUDATA structure pointed by pMenuData. *
\* */
fprintf(Pc2Profile, "MENUITEM\n");
fprintf(Pc2Profile, "PgmTitle: %s\n", pMenuData->PgmTitle);
fprintf(Pc2Profile, "PgmName: %s\n", pMenuData->PgmName);
fprintf(Pc2Profile, "PgmDirectory: %s\n", pMenuData->PgmDirectory);
fprintf(Pc2Profile, "PgmInputs: %s\n", pMenuData->PgmInputs);
/* Write DOS Settings only if available */
if(strlen(pMenuData->PgmDosSettings)!=0)
{
fprintf(Pc2Profile, "DOSSETTINGS BEGIN\n");
fprintf(Pc2Profile, "%s", pMenuData->PgmDosSettings);
fprintf(Pc2Profile, "DOSSETTINGS END\n");
}
fprintf(Pc2Profile, "SessionType: %lu\n", (ULONG)pMenuData->SessionType);
fprintf(Pc2Profile, "PgmControl: %lu\n", (ULONG)pMenuData->PgmControl);
fprintf(Pc2Profile, "FgBg: %lu\n", (ULONG)pMenuData->FgBg);
fprintf(Pc2Profile, "InitXPos: %lu\n", (ULONG)pMenuData->InitXPos);
fprintf(Pc2Profile, "InitYPos: %lu\n", (ULONG)pMenuData->InitYPos);
fprintf(Pc2Profile, "InitXSize: %lu\n", (ULONG)pMenuData->InitXSize);
fprintf(Pc2Profile, "InitYSize: %lu\n", (ULONG)pMenuData->InitYSize);
fprintf(Pc2Profile, "PriorityClass: %lu\n", (ULONG)pMenuData->PriorityClass);
fprintf(Pc2Profile, "PriorityDelta: %ld\n", (LONG)pMenuData->PriorityDelta);;
}
/* *\
* If one is available, get the next element in the linked list, else we are at the end *
* either at a leaf or at the real last element, in both cases shell back one level. *
* Shell back either exits this procedure completle (we have written the complete *
* linked list) or on level (we have written a complete submenu leaf). *
\* */
if(pMenuData->Next!=NULL) pMenuData=pMenuData->Next;
else break;
} while(TRUE);
}
/*--------------------------------------------------------------------------------------*\
* This recursive procedure searches through the linked list for an element. *
* Req: *
* pMD ........... A pointer to the first element to search on *
* id ............ Pointer to the ID to search for (pointer because we don't want *
* to get a copy during recursion *
* Returns: *
* MENUDATA * .... Pointer to match or NULL if not found *
\*--------------------------------------------------------------------------------------*/
MENUDATA *SearchItem(MENUDATA *pMD, ULONG *id)
{
static MENUDATA *pMDReturn;
do
{
/* If found, save the pointer of it, set ID to the
value 1 which never occures in the linked list
to detect the match at the end of the recursion */
if(pMD->id==*id) { pMDReturn=pMD; *id=TRUE; break; }
/* Shell into the Submenus */
if(pMD->Item==ENTRYSUBMENU)
SearchItem(pMD->Submenu, id);
if(pMD->Next!=NULL) pMD=pMD->Next; /* Keep on searching until found or end of linked list */
else
{ /* We're at the end of the linked list */
if(*id!=TRUE) pMDReturn=NULL; /* If we didn't find the item return NULL */
break;
}
} while(TRUE);
return(pMDReturn);
}
/*--------------------------------------------------------------------------------------*\
* This procedure adds/changes/query/removes an item to/from the Popup-Menu. *
* Req: *
* msg ........... What to do *
* mp1 ........... Parameter 1 *
* mp2 ........... Parameter 2 *
* Returns: *
* MRESULT ....... Returned value of function *
\*--------------------------------------------------------------------------------------*/
MRESULT SetPopupMenu(ULONG msg, MPARAM mp1, MPARAM mp2)
{
MENUDATA *pMD;
ULONG id;
MENUITEM miMI; /* Update menus with this structure */
HWND hwndMenu; /* Menu window handle */
HWND hwndSubMenu; /* Window handle of a pulldown menu within the menu bar */
MRESULT mr; /* PM API result */
BOOL bResult;
bResult=FALSE;
switch(msg)
{
/* *\
* Syntax: MM_INSERTITEM(MENUITEM|SUBMENU), MENUDATA *pMD, ULONG id *
\* */
/* *\
* Insert a Menuitem, a Submenu or Menuentry, into a (Sub)menu, even if it is empty. *
\* */
case MM_INSERTITEMMENUITEM:
/* *\
* Insert a Menuitem, a Submenu or Menuentry as the first child entry of a parent *
* Submenu. *
\* */
case MM_INSERTITEMSUBMENU:
pMD=PVOIDFROMMP(mp1); /* Get pointer to MENUDATA structure to insert */
id=LONGFROMMP(mp2); /* Get id to insert after */
/* *\
* An item (Menuitem or Submenu) is to be inserted into the Popup-Menu, either after *
* a Menuitem or as the first item of a/the (Sub)menu. *
\* */
if(WinSendMsg(
hwndPopupMenu,
MM_QUERYITEM, /* Query a menuitem */
MPFROM2SHORT(id, TRUE), /* Identifier, include submenus */
(MPARAM)&miMI)==FALSE) /* Into MENUITEM structure */
miMI.hwndSubMenu=0;
/* If the item after we insert is a Submenu, then
use the Submenu handle to insert new items,
otherwise use the handle of the previous item */
if((miMI.hwndSubMenu!=0) && (msg==MM_INSERTITEMSUBMENU))
{
hwndMenu=miMI.hwndSubMenu;
id=MIT_END;
}
if(msg==MM_INSERTITEMMENUITEM)
{ /* If this is the first item, use the Popup-Menu
window handle */
if(pMD->Back==NULL) hwndMenu=hwndPopupMenu;
/* If we insert after an available item, get it's
window handle */
else hwndMenu=(pMD->Back)->hwndItem;
}
/* If previous exists, insert after the item with
ID id */
if(id!=(ULONG)MIT_END) miMI.iPosition++;
else miMI.iPosition=id; /* Insert at end MIT_END */
miMI.afAttribute=0; /* Special attribute */
miMI.id=pMD->id; /* Item identifier */
miMI.hItem=0; /* No handle */
if(pMD->Item==ENTRYSUBMENU)
{ /* If we insert a Submenu, than we need to obtain
a handle to create one */
hwndSubMenu=WinCreateMenu( /* Create a submenu menuitem */
hwndMenu, /* Owner- and parent-window handle */
NULL); /* Binary menu template */
miMI.afStyle=MIS_SUBMENU; /* Style to insert */
miMI.hwndSubMenu=hwndSubMenu; /* Pulldown menu */
}
else
{ /* We insert a Menuitem */
miMI.afStyle=MIS_TEXT; /* Style to insert */
miMI.hwndSubMenu=0; /* No pulldown menu */
}
pMD->hwndItem=hwndMenu; /* Save the window handle of the item */
mr=WinSendMsg(
hwndMenu,
MM_INSERTITEM, /* Insert a menu item */
&miMI, /* Item to insert */
pMD->PgmTitle); /* Text to insert */
if(((SHORT)mr==MIT_ERROR) || ((SHORT)mr==MIT_MEMERROR))
GEN_ERR(hab, hwndFrame, hwndClient);
else bResult=TRUE;
break;
/* *\
* Syntax: MM_MOVEMENUITEM, MENUDATA *pMDSource, MENUDATA *pMDDestination *
\* */
case MM_MOVEMENUITEM:
/* *\
* Move a MENUITEM structure with idSource after the idDestination. *
\* */
{
MENUDATA *pMDSource;
MENUDATA *pMDDestination;
ULONG idSource; /* Id of Menuitem to be moved */
ULONG idDestination; /* Id of Menuitem after which the removed Menuitem
will be inserted */
MENUITEM miSource; /* MENUITEM structure of to be moved Menuitem */
MENUITEM miDestination; /* MENUITEM structure of Menuitem after which
the removed Menuitem will be inserted */
pMDSource=PVOIDFROMMP(mp1);
pMDDestination=PVOIDFROMMP(mp2);
idSource=pMDSource->id; /* Get id of to be removed Menuitem */
idDestination=pMDDestination->id; /* Get id of Menuitem after which removed Menuitem
will be inserted */
/* *\
* If the source and destination Menuitem are elements of the same level then they have *
* the same item handle. *
\* */
if(pMDSource->hwndItem==pMDDestination->hwndItem)
bResult=TRUE;
else
bResult=FALSE;
/* Query all (Sub)menus for to be moved Menuitem */
WinSendMsg(hwndPopupMenu, MM_QUERYITEM,
MPFROM2SHORT(idSource, TRUE), (MPARAM)&miSource);
/* Delete the to be moved Menuitem. Don't use MM_DELETEITEM
because it frees all OS/2 internal structures,
whereas MM_REMOVEITEM doesn't free them */
WinSendMsg(hwndPopupMenu, MM_REMOVEITEM,
MPFROM2SHORT(idSource, TRUE), (MPARAM)NULL);
/* Query all (Sub)menus for Menuitem after which
the removed Menuitem will be inserted */
WinSendMsg(hwndPopupMenu, MM_QUERYITEM,
MPFROM2SHORT(idDestination, TRUE), (MPARAM)&miDestination);
if(bResult==TRUE)
{ /* If both are on the same current level of Menuitems
insert removed Menuitem after destination Menuitem */
if(pMDDestination==pPopupMenu)
/* If the destination of the Source Menuitem is in the
root of all(Sub)menus, than insert at 0-based
position 2, because position 0 is used by PC/2
Setup and position 1 is the seperator bar */
miSource.iPosition=2;
else /* If the destination of the Source Menuitem follows
any previous Menuitem in the same level, just
insert it one position behind */
miSource.iPosition=++miDestination.iPosition;
hwndMenu=pMDDestination->hwndItem;
mr=WinSendMsg(hwndMenu, MM_INSERTITEM, &miSource, pMDSource->PgmTitle);
}
else
{ /* If the destination of the source Menuitem is the
first position of a Submenu, insert is a 0-base
posisition 0 */
hwndMenu=miDestination.hwndSubMenu;
miSource.iPosition=0;
mr=WinSendMsg(hwndMenu, MM_INSERTITEM, &miSource, pMDSource->PgmTitle);
}
}
break;
/* *\
* Syntax: MM_SETITEMTEXT, MENUDATA *pMD, ULONG id *
\* */
case MM_SETITEMTEXT:
pMD=PVOIDFROMMP(mp1); /* Get pointer to MENUDATA structure to update */
id=LONGFROMMP(mp2); /* Get id to update */
/* *\
* A available menuitem was selected to change. Change the text of the menuitem to the *
* new one. *
\* */
if(WinSendMsg(
hwndPopupMenu,
MM_SETITEMTEXT, /* Set the text of a menuitem */
MPFROMSHORT(id), /* Item ID */
(MPARAM)pMD->PgmTitle)==FALSE) /* New menuitem text */
GEN_ERR(hab, hwndFrame, hwndClient);
else bResult=TRUE;
break;
case MM_DELETEITEM:
pMD=PVOIDFROMMP(mp1); /* Get pointer to MENUDATA structure to delete */
id=LONGFROMMP(mp2); /* Get id to delete */
/* *\
* A available menuitem was selected to delete. Delete the specified menuitem. *
\* */
{
if(pMD->Item==ENTRYSUBMENU)
{ /* It the menuitem is a Submenu, also delete the
first item of it (which should be empty) */
mr=WinSendMsg(
hwndPopupMenu,
MM_DELETEITEM, /* Delete a menuitem */
/* Item ID, include Submenus */
MPFROM2SHORT((pMD->Submenu->id), TRUE),
(MPARAM)NULL);
}
mr=WinSendMsg(
hwndPopupMenu,
MM_DELETEITEM, /* Delete a menuitem */
MPFROM2SHORT(id, TRUE), /* Item ID, include Submenus */
(MPARAM)NULL);
bResult=TRUE;
}
break;
}
return(MPFROMSHORT(bResult));
}
/*--------------------------------------------------------------------------------------*\
* This procedure handles to copy a fully qualified path & filename into the corres- *
* ponding entryfields of the Program Installation dialog. *
* Req: *
* hwndDlg ....... handle of Program installation dialog *
* pucFullFileName fully qualified path & filename of application to add *
* the name of an object to add *
* bObject ....... TRUE if it is an WPS object *
\*--------------------------------------------------------------------------------------*/
void InstallFilename2Dialog(HWND hwndDlg, UCHAR *pucFullFileName, BOOL bObject)
{
UCHAR ucBuffer[260]; /* Longer than 256 because of "s */
UCHAR *pucTemp;
BOOL bBatchFile=FALSE;
ULONG ulAppType; /* Type of application we're installing */
USHORT usSessionType;
strupr(pucFullFileName); /* First convert to uppercase to simplify compares */
if(bObject==TRUE)
{
usSessionType=SSF_TYPE_WPSOBJECT; /* It is an WPS object */
/* Set title and object name info entryfields */
WinSetDlgItemText(hwndDlg, PIEF_PROGRAMTITLE, pucFullFileName);
WinSetDlgItemText(hwndDlg, PIEF_PATHFILENAME, pucFullFileName);
WinSetDlgItemText(hwndDlg, PIEF_PARAMETERS, "");
WinSetDlgItemText(hwndDlg, PIEF_DIRECTORY, "");
}
else
{ /* It is a file */
/* Get the type of application */
DosQueryAppType(pucFullFileName, &ulAppType);
usSessionType=SSF_TYPE_DEFAULT; /* Assume Shell determined for default */
if((ulAppType&0x7)==FAPPTYP_WINDOWAPI) usSessionType=SSF_TYPE_PM;
if((ulAppType&0x7)==FAPPTYP_WINDOWCOMPAT) usSessionType=SSF_TYPE_WINDOWABLEVIO;
if(ulAppType&FAPPTYP_DOS) usSessionType=SSF_TYPE_WINDOWEDVDM;
}
/* Reflect the application type with the Program
Type radiobuttons */
WinSendMsg(hwndDlg, WM_SETUPPROGRAMTYPE,
MPFROMSHORT(usSessionType), (MPARAM)NULL);
if(bObject==FALSE)
{
/* Now test for a OS/2 batch file */
if(strstr(pucFullFileName, ".CMD")!=NULL)
{
bBatchFile=TRUE;
if(strchr(pucFullFileName, ' ')!=NULL)
{ /* If path and filename contains spaces, insert
two quotation marks */
strcpy(ucBuffer, "/c \"\"");
strcat(ucBuffer, pucFullFileName);
strcat(ucBuffer, "\"\"");
}
else
{ /* Else add just /c to [path]filename.cmd */
strcpy(ucBuffer, "/c ");
strcat(ucBuffer, pucFullFileName);
}
}
/* Now test for a DOS batch file */
if(strstr(pucFullFileName, ".BAT")!=NULL)
{
bBatchFile=TRUE;
strcpy(ucBuffer, "/c "); /* Add just /c to [path]filename.cmd */
strcat(ucBuffer, pucFullFileName);
}
if(bBatchFile==TRUE)
{ /* Set batchfile as parameter and empty path & filename */
WinSetDlgItemText(hwndDlg, PIEF_PARAMETERS, ucBuffer);
WinSetDlgItemText(hwndDlg, PIEF_PATHFILENAME, "");
}
else
{ /* Set full qualified path and empty parameters */
WinSetDlgItemText(hwndDlg, PIEF_PATHFILENAME, pucFullFileName);
WinSetDlgItemText(hwndDlg, PIEF_PARAMETERS, "");
}
strcpy(ucBuffer, pucFullFileName); /* Save full path & filename */
/* Extract filename */
pucTemp=pucFullFileName+strlen(pucFullFileName);
for( ; (*pucTemp!='\\') && (pucTemp>=pucFullFileName); pucTemp--);
/* Set filename */
WinSetDlgItemText(hwndDlg, PIEF_PROGRAMTITLE, (pucTemp+1));
*pucTemp='\0'; /* Get path as working directory */
/* Set working directory */
WinSetDlgItemText(hwndDlg, PIEF_DIRECTORY, pucFullFileName);
}
}
/*--------------------------------------------------------------------------------------*\
* This procedure disables or enables child windows of a dialog window according to the *
* bDisable flag. *
* Req: *
* hwndDlg ....... handle of Program installation dialog *
* usDialogIDs ... array of IDs of the child windows of a dialog *
* usItemCount ... number of IDs in the array *
* ulStyle ....... WS_VISIBLE | WS_DISABLED or not *
\*--------------------------------------------------------------------------------------*/
void DisableDialogItem(HWND hwndDlg, USHORT usDialogIDs[], USHORT usItemCount, ULONG ulStyle)
{
USHORT usTemp;
if(ulStyle&WS_DISABLED)
/* Enumerate and disable all child windows */
for(usTemp=0; usTemp<usItemCount; usTemp++)
WinEnableWindow(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]), FALSE);
else
/* Enumerate and enable all child windows */
for(usTemp=0; usTemp<usItemCount; usTemp++)
WinEnableWindow(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]), TRUE);
if(ulStyle&WS_VISIBLE)
/* Enumerate and show all child windows */
for(usTemp=0; usTemp<usItemCount; usTemp++)
WinSetWindowPos(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]),
0, 0, 0, 0, 0, SWP_SHOW);
else
/* Enumerate and hide all child windows */
for(usTemp=0; usTemp<usItemCount; usTemp++)
WinSetWindowPos(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]),
0, 0, 0, 0, 0, SWP_HIDE);
}